package drds.plus.sql_process.abstract_syntax_tree.execute_plan.query;

import drds.plus.sql_process.abstract_syntax_tree.IExecutePlanVisitor;
import drds.plus.sql_process.abstract_syntax_tree.ObjectCreateFactory;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.Item;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.function.Filter;
import drds.plus.sql_process.utils.OptimizerUtils;

import java.util.LinkedList;
import java.util.List;

public class JoinImpl extends QueryImpl implements Join {

    /**
     * 左面join 子树 所有join都以key-value对的形式存在
     */
    protected Query leftNode;
    /**
     * 右面join 子树 所有join的子节点都以key-value对的形式存在
     */
    protected Query rightNode;
    /**
     * 左面join的列
     */
    protected List<Item> leftJoinColumnList = new LinkedList<Item>();
    /**
     * 右面join的对应列
     */
    protected List<Item> rightJoinColumnList = new LinkedList<Item>();

    /**
     * join的策略 ，具体请看对应解说
     */
    protected JoinStrategy joinStrategy;
    /**
     * 左outer join,即使右表没有匹配的对应行，也输出左行 默认是false,也就是内联join
     */
    protected Boolean leftOuter;
    /**
     * 右outer join 即使左表没有匹配的对应行，也输出右行 默认是false，也就是内联join
     */
    protected Boolean rightOuter;
    protected Filter whereFilter;

    public Join copy() {
        Join join = ObjectCreateFactory.createJoin();
        copySelfTo((QueryImpl) join);
        join.setJoinNodes((Query) this.getLeftNode().copy(), (Query) this.getRightNode().copy());
        join.setJoinItemList(this.getLeftJoinColumnList(), this.getRightJoinColumnList());
        join.setJoinStrategy(this.getJoinStrategy());
        join.setLeftOuterJoin(this.isLeftOuterJoin());
        join.setRightOuterJoin(this.isRightOuterJoin());
        join.setWhereFilter(OptimizerUtils.copyFilter(this.getWhereFilter()));
        return join;
    }

    public void accept(IExecutePlanVisitor executePlanVisitor) {
        executePlanVisitor.visit(this);
    }

    public void setJoinNodes(Query leftNode, Query rightNode) {
        this.leftNode = leftNode;
        this.rightNode = rightNode;

    }

    public void setLeftNode(Query leftNode) {
        this.leftNode = leftNode;

    }

    public Query getLeftNode() {
        return leftNode;
    }

    public void setRightNode(Query rightNode) {
        this.rightNode = rightNode;

    }

    public Query getRightNode() {
        return rightNode;
    }

    public void setJoinItemList(List<Item> leftJoinColumnList, List<Item> rightJoinColumnList) {
        this.leftJoinColumnList = leftJoinColumnList;
        this.rightJoinColumnList = rightJoinColumnList;

    }

    public void addLeftJoinColumn(Item item) {
        this.leftJoinColumnList.add(item);

    }

    public List<Item> getLeftJoinColumnList() {
        return leftJoinColumnList;
    }

    public void addRightJoinOnColumn(Item item) {
        rightJoinColumnList.add(item);

    }

    public List<Item> getRightJoinColumnList() {
        return rightJoinColumnList;
    }

    public void setJoinStrategy(JoinStrategy joinStrategy) {
        this.joinStrategy = joinStrategy;

    }

    public JoinStrategy getJoinStrategy() {
        return joinStrategy;
    }

    public Boolean isLeftOuterJoin() {
        return leftOuter;
    }

    public Boolean isRightOuterJoin() {
        return rightOuter;
    }

    public void setLeftOuterJoin(boolean leftOuter) {
        this.leftOuter = leftOuter;

    }

    public void setRightOuterJoin(boolean rightOuter) {
        this.rightOuter = rightOuter;

    }

    public Filter getWhereFilter() {
        return whereFilter;
    }

    public void setWhereFilter(Filter whereFilter) {
        this.whereFilter = whereFilter;

    }


}
